package com.yl.applicationsecurity.utils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
/**
 * @author 鹤仙问鹿仙
 * @program: Application-security
 * @description:  后端对接签名验证类
 * @date 2025-01-14 15:11:18
 */


public class SignatureUtil {

    private static final String HMAC_SHA256 = "HmacSHA256";

    /**
     * 生成签名
     *
     * @param params 请求参数（按键名排序后的 Map）
     * @param secret 密钥
     * @return 生成的签名
     */
    public static String generateSignature(Map<String, String> params, String secret) {
        try {
            // 将参数按键名排序
            Map<String, String> sortedParams = new TreeMap<>(params);

            // 拼接参数为字符串 (key1=value1&key2=value2...)
            StringBuilder dataToSign = new StringBuilder();
            for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
                if (entry.getValue() != null && !entry.getValue().isEmpty()) {
                    dataToSign.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
                }
            }
            // 删除末尾的 "&"
            if (dataToSign.length() > 0) {
                dataToSign.deleteCharAt(dataToSign.length() - 1);
            }

            // 创建 HMAC-SHA256 签名
            Mac mac = Mac.getInstance(HMAC_SHA256);
            SecretKeySpec secretKeySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), HMAC_SHA256);
            mac.init(secretKeySpec);

            // 签名结果
            byte[] hash = mac.doFinal(dataToSign.toString().getBytes(StandardCharsets.UTF_8));

            // 返回 Base64 编码的签名
            return Base64.getEncoder().encodeToString(hash);
        } catch (Exception e) {
            throw new RuntimeException("签名生成失败", e);
        }
    }

    /**
     * 验证签名
     *
     * @param params    请求参数
     * @param secret    密钥
     * @param signature 请求中的签名
     * @return 是否验证通过
     */
    public static boolean verifySignature(Map<String, String> params, String secret, String signature) {
        // 生成签名
        String generatedSignature = generateSignature(params, secret);
        // 比较签名
        return generatedSignature.equals(signature);
    }

    public static void main(String[] args) {
        // 示例数据
        Map<String, String> params = new HashMap<>();
//        params.put("url", "1111111");
//        params.put("system", "22222");
//        params.put("nation", "SA");
//        params.put("name", "33333");
//        params.put("requtestText", "44444");
//        params.put("reponeseText", "55555");


//        params.put("url", "1");
//        params.put("firstdiscovery", "0");
//        params.put("nation", "CN");
//url=1111111&system=22222&nation=SA&name=33333&requtestText=44444&reponeseText=55555
        //Map<String, String> params = new HashMap<>();
//        params.put("name", "OSS枚举");
//        params.put("url", "www.baidu.com");
//        params.put("nation", "SA");
//        params.put("description", "漏洞描述");
//        params.put("excessiveType", "2");
//        params.put("url", "http://22222");
//        params.put("systemName", "uat-wd");
//        params.put("level", "jiamengshang");
//        params.put("country", "CN");
//        params.put("request", "cXdlaXF3ZXF3ZXdx");
//        params.put("response", "MjMxMjMxMzIxMzIx");
//        params.put("dateTimeStr", "2025-02-19 14:30:00");
        params.put("", "[\n" +
                "    {\n" +
                "        \"url\": \"www.baidu.com\",\n" +
                "        \"systemName\": \"222\",\n" +
                "        \"excessiveType\": 1,\n" +
                "        \"level\": \"ceshi\",\n" +
                "        \"country\": \"SA\",\n" +
                "        \"request\": \"cnVub29iMTIzMTIzMTIz\",\n" +
                "        \"response\": \"cnVub29iMTIzMTIzMTIz\",\n" +
                "        \"dateTimeStr\": \"2025-02-19 14:30:00\"\n" +
                "    }\n" +
                "]");


        String secret = "s6wjRJi5AMZtN6y7ecwCdJai3527nMKZ";

        // 生成签名
        String signature = generateSignature(params, secret);
        System.out.println("生成的签名: " + signature);

        // 验证签名
        boolean isValid = verifySignature(params, secret, signature);
        System.out.println("签名是否有效: " + isValid);
    }
}

